package com.heima.wemedia.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.model.dtos.PageResponseResult;
import com.heima.model.dtos.ResponseResult;
import com.heima.model.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.dtos.WmNewsDto;
import com.heima.model.wemedia.dtos.WmNewsPageReqDto;
import com.heima.model.wemedia.pojos.WmMaterial;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmNewsMaterial;
import com.heima.wemedia.mapper.WmMaterialMapper;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.mapper.WmNewsMaterialMapper;
import com.heima.wemedia.service.WmNewsAutoScanService;
import com.heima.wemedia.service.WmNewsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 张一恒
 * @version 1.0
 * @description:
 * @date 2023/1/11 23:04
 */
@Service
@Slf4j
public class WmNewsServiceImpl extends ServiceImpl<WmNewsMapper, WmNews> implements WmNewsService {


    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Autowired
    private WmNewsMaterialMapper wmNewsMaterialMapper;

    @Autowired
    private WmMaterialMapper wmMaterialMapper;

    @Autowired
    private WmNewsAutoScanService wmNewsAutoScanService;

    /**
     * @param userId
     * @param dto
     * @return com.heima.model.dtos.ResponseResult
     * @description 查询文章
     * @author 31115
     * @date 2023/1/11 23:06
     */
    @Override
    public ResponseResult findAll(Integer userId, WmNewsPageReqDto dto) {

        try {
            //校验分页
            dto.checkParam();

            LambdaQueryWrapper<WmNews> wrapper = new LambdaQueryWrapper<>();
            Page page = new Page(dto.getPage(), dto.getSize());
            for (Field field : dto.getClass().getDeclaredFields()) {
                //把私有属性公有化
                field.setAccessible(true);
                Object object = field.get(dto);
                if (Objects.isNull(object)) {
                    //先判断什么都不传的 根据id查询全部
                    wrapper.eq(WmNews::getUserId, userId);
                }
            }

            wrapper.eq(WmNews::getUserId, userId)
                    //排序
                    .orderByDesc(WmNews::getCreatedTime)
                    //频道
                    .eq(!StringUtils.isEmpty(dto.getChannelId()), WmNews::getChannelId, dto.getChannelId())
                    //状态
                    .eq(!StringUtils.isEmpty(dto.getStatus()), WmNews::getStatus, dto.getStatus())
                    //关键字
                    .like(!StringUtils.isEmpty(dto.getKeyword()), WmNews::getTitle, dto.getKeyword());
            //时间
//                    .between(!StringUtils.isEmpty(dto.getBeginPubdate()) && !StringUtils.isEmpty(dto.getEndPubdate()),
//                            WmNews::getPublishTime, dto.getBeginPubdate(), dto.getEndPubdate());

            if (!StringUtils.isEmpty(dto.getBeginPubdate()) && !StringUtils.isEmpty(dto.getEndPubdate())) {
                SimpleDateFormat sim2 = new SimpleDateFormat("yyyy-MM-dd");
                String beg = sim2.format(dto.getBeginPubdate());
                String end = sim2.format(dto.getEndPubdate());
                wrapper.apply(
                        "date_format (publish_time,'%Y-%m-%d') >= date_format('" + beg + "'," +
                                "'%Y-%m-%d')")
                        .apply(
                                "date_format (publish_time,'%Y-%m-%d') <= date_format('" + end + "','%Y-%m-%d')");
            }

            page(page, wrapper);
            ResponseResult result = new PageResponseResult(dto.getPage(), dto.getSize(),
                    Integer.parseInt(page.getTotal() + ""));
            result.setData(page.getRecords());
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            log.debug("查询文章出错：{}", e.getMessage());
            return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR);
        }
    }

    /**
     * @param userId
     * @param dto
     * @return com.heima.model.dtos.ResponseResult
     * @description 修改、新增、新增草稿到文章表
     * @author 31115
     * @date 2023/1/12 13:39
     */
    @Override
    public ResponseResult submit(Integer userId, WmNewsDto dto) {
        //校验传过来的字段
        if (StringUtils.isEmpty(dto.getContent())) {
            log.debug("修改、新增、等文章内容为空：{}", dto.getContent());
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE, "文章内容为空");
        }
        if (StringUtils.isEmpty(dto.getTitle())) {
            log.debug("修改、新增、等文章标题为空：{}", dto.getTitle());
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE, "文章标题为空");
        }

        //如果是-1则临时修改成null，不然新增会报错
        if (dto.getType() == -1) {
            dto.setType(null);
            log.debug("submit接口：如果是Type-1则临时修改成null，不然新增会报错");
        }

        //新增或修改文章
        WmNews wmNews = this.addOrUpdateWmNews(userId, dto);


        //判断是否为草稿
        if ("0".equals(dto.getStatus().toString())) {
            log.debug("submit接口：文章类型为草稿：{}",dto.getStatus().toString());
            return ResponseResult.okResult(AppHttpCodeEnum.CAOGAO);
        }

        //取出文章内容中的图片url
        List<String> url = getWmNewsOrMaterialImagesUrl(dto);
        log.debug("submit接口：取出文章内容中的图片url成功：{}，数量：{}",url,url.size());

        //关联内容中的图片与素材的关系
        this.saveWmNewsMaterial(url, wmNews.getId(),  0);//0等于内容图片
        log.debug("submit接口：关联内容中的图片与素材的关系成功");


        //关联封面中的图片与素材的关系
        this.saveWmNewsMaterial2(url, wmNews, dto,  1); //1等于封面图片
        log.debug("submit接口：关联封面中的图片与素材的关系成功");

        //用户提交成功后异步调用自动审核业务进行审核发布
        wmNewsAutoScanService.autoScanWmNews(wmNews.getId());

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    //关联封面中的图片与素材的关系
    @Transactional
    @Override
    public void saveWmNewsMaterial2(List<String> url, WmNews wmNews, WmNewsDto dto, Integer type) {

        //拿到前端传来的内容图片
        List<String> images = dto.getImages();

        //判断内容图片是否为大于等于1小于3或大于等于3 为0则文章type修改成0 0等于不传
        if (dto.getType() == null) { // 自动
            log.debug("submit接口：关联封面中的图片与素材的关系用户："+wmNews.getUserId()+" 选择自动获取");
            //内容
            if (url.size() >= 1) {
                if (url.size() >= 1 && url.size() < 3) {
                    //获取第一张
                    images = url.stream().limit(1).collect(Collectors.toList());
                    wmNews.setType(1);
                    log.debug("submit接口：关联封面中的图片与素材的关系用户："+wmNews.getUserId()+" 选择自动获取前一张");
                } else if (url.size() >= 3) {
                    //获取三张
                    images = url.stream().limit(3).collect(Collectors.toList());
                    wmNews.setType(3);
                    log.debug("submit接口：关联封面中的图片与素材的关系用户："+wmNews.getUserId()+" 选择自动获取前三张");
                }
            }else {
                //无图
                wmNews.setType(0);
                log.debug("submit接口：关联封面中的图片与素材的关系用户："+wmNews.getUserId()+" 选择自动获取无图");
            }
            //更新wmnews表
            wmNews.setImages(org.apache.commons.lang3.StringUtils.join(images, ","));
            this.update(wmNews,Wrappers.<WmNews>lambdaQuery().eq(WmNews::getId,wmNews.getId()));

        }
        //插入关联封面中的图片与素材的关系
        saveWmNewsMaterial(images, wmNews.getId(), type);
    }

    //通用插入关联内容中的图片与素材的关系方法
    @Transactional
    @Override
    public void saveWmNewsMaterial(List<String> url, Integer wmNewsId, Integer type) {

        if (url.size()>=1){
            //获取素材表数据
            log.debug("submit接口：关联内容中的图片与素材的关系内容图片数量：{}",url.size());
            List<WmMaterial> wmMaterials =
                    wmMaterialMapper.selectList(Wrappers.<WmMaterial>lambdaQuery().in(WmMaterial::getUrl, url));

            List<Integer> wmMaterialId = wmMaterials.stream().map(WmMaterial::getId).collect(Collectors.toList());

            wmNewsMaterialMapper.saveBatch(wmMaterialId, wmNewsId, type);
        }

    }


    //取出文章内容中的图片url
    private List<String> getWmNewsOrMaterialImagesUrl(WmNewsDto dto) {
        //取出文章内容中的图片url
        List<Map> imageList = JSON.parseArray(dto.getContent(), Map.class);
        List<String> url = new ArrayList<>();
        for (Map map : imageList) {
            if ("image".equals(map.get("type"))) {
                //取出url
                String imageUrl = map.get("value").toString();
                url.add(imageUrl);
            }
        }
        return url;
    }

    //新增或修改文章
    @Transactional
    @Override
    public WmNews addOrUpdateWmNews(Integer userId, WmNewsDto dto) {
        //转换文章封面图片
        List<String> images = dto.getImages();
        String image = null;
        if (images != null) {
            log.debug("submit接口：新增或修改文章内容图片不为空：{}",images.size());
            image = org.apache.commons.lang3.StringUtils.join(images, ",");
        }
        WmNews wmNews = new WmNews();
        BeanUtils.copyProperties(dto, wmNews);
        wmNews.setUserId(userId);
        wmNews.setImages(image);
        //默认上架  0下架   1上架
        wmNews.setEnable(1);
        wmNews.setCreatedTime(new Date());
        wmNews.setSubmitedTime(new Date());
        //id为空是新增
        if (!StringUtils.isEmpty(dto.getId())) {
            //修改
            //删除已关联素材关系
            wmNewsMaterialMapper.delete(Wrappers.<WmNewsMaterial>lambdaQuery().eq(WmNewsMaterial::getNewsId,
                    wmNews.getId()));
            this.updateById(wmNews);
            log.debug("submit接口：新增或修改文章 修改成功，关联素材关系删除成功：{}",wmNews);
            return wmNews;
        } else {
            this.save(wmNews);
            log.debug("submit接口：新增或修改文章 新增成功：{}",wmNews);
            return wmNews;
        }
    }
}
